home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #067 (1990-04)(Amiga User Group Deutschland e.V.).zip / Franz PD Disk #067 (1990-04)(Amiga User Group Deutschland e.V.).adf / Pascal_Info / Pascal_Info
Text File  |  1989-07-02  |  54KB  |  1,350 lines

  1.  
  2.     Hallo Leute,
  3.     hier die deutsche Übersetzung der PCQ-Anleitung.
  4.  
  5.     Da das Copyright auf der deutschen Übersetzung weiter beim
  6.     Inhaber des Originalcopyrights (d.h. Pat) liegt, will ich erst
  7.     gar keins erheben und sage:
  8.  
  9.     WEITERGEBEN - WEITERGEBEN - WEITERGEBEN - WEITERGEBEN
  10.  
  11.     Aber: Haltet Euch an Pat Bestimmungen!
  12.  
  13.     Vinorkis ^O^
  14.  
  15. --------------------------------------------------------------------------
  16.  
  17.        Überarbeitet und an V1.1 angepasst von Ølli.
  18.  
  19.     Diese Übersetzung ist bei weitem nicht vollständig
  20.     und enthält jede Menge Fehler. Im Zweifelsfalle also
  21.     immer auf die Originalanleitung ausweichen.
  22.  
  23.     Dieser Text sollte aber für einen ersten Überblick reichen!
  24.  
  25. ---------------------------------------------------------------------------
  26.  
  27.  
  28.  
  29.                PCQ Version 1.1
  30.       Ein sehr einfacher Pascal Compiler für den Amiga
  31.                von Patrick Quaid
  32.  
  33.  
  34.     PCQ (das bedeuted Pascal Compiler, ähem, Q.... Sehr, mir fiel kein Name
  35. ein, so habe ich einfach meine Initalien benutzt, ok?) ) ist ein einfacher
  36. Pascal Sub-Set Compiler, der Assembler-Code generiert. Er ist zwar kein
  37. Public-Domain-Program im eigentlichen Sinne (denn ich behalte mir das
  38. Copyright auf den Source Code, die Laufzeit Bibliothek mit deren Source
  39. Code, den Compiler und der Dokumentation vor), aber es darf weitergegeben
  40. werden, solange alle Files unverändert auf der Diskette verbleiben (mit
  41. Ausnahme des Assemblers und des Linkers). Der Compiler ist zwar langsam
  42. und hat Probleme mit einigen Sachen, aber er ist auf jeden Fall sein Geld
  43. wert. Um es zusammenzufassen:
  44.  
  45. Das Schlechte:
  46.  
  47.   Der Compiler ist sehr langsam.
  48.  
  49.   Er unterstützt keine Sets.
  50.  
  51.   Der Code wird nicht optimiert und ist deshalb langsam, groß und
  52.     sieht bescheürt aus.
  53.  
  54.   Die meisten Fehler erzeugen eine Endlosschleife.
  55.  
  56.  
  57. Das Positive:
  58.  
  59.   Er funktioniert, im großen und Ganzen...
  60.  
  61.   Der Compiler unterstützt Include-Files
  62.  
  63.   Er erlaubt externe Verweise (Referenzen), obwohl diese von Hand geprüft
  64.       werden müssen (das hier ist kein Modula-2)
  65.  
  66.   Unterstützt Strukturen (Records), Aufzählungstypen (enumerated types),
  67.       Zeiger (Pointers), Arrays und Strings.
  68.  
  69.   Typen-Konvertierungen wie in Modula-2 werden unterstützt. Mit anderen
  70.      Worten: Ausdrücke wie "integer('d')" sind möglich. Einige Besonderheiten
  71.  
  72.   Einige Besonderheiten von Turbo und Quick-Pascal wie "Exit" innerhalb einer
  73.   Prozedur, Operatoren wie "Shl" und "Shr" und Typen-Konstanten sind
  74.   eingebaut worden.
  75.  
  76.   Es können beliebig viele const, var, type, prcödure und function-Blöcke
  77.   definiert werden, in jeder Reihenfolge.
  78.  
  79.   Er kostet nichts (solange sie nicht auf gewisse Sonderangebote deutscher
  80.   PD-Händler reinfallen, Anm. d. Übersetzers).
  81.  
  82.  
  83.              IHNALTSVERZEICHNIS
  84.              ------------------
  85.  
  86.  
  87.     Diese Bedienungsanleitung sollte mit einem sog. File-Reader, also einem
  88. speziellen ASCII-Datei-Leseprogramm oder einem Text-Editor gelesen werden.
  89. Deshalb hier keine Seiten-, sondern Zeilennummern (ohne Gewähr, Anm. d.
  90. Übersetzers :-)
  91.  
  92.  
  93. Abschnitt                              Zeile
  94.  
  95. Arbeiten mit dem PCQ .......................................   128
  96. Beschreibung der Fehler ....................................   238
  97. Vordefinierte Elemente .....................................   271
  98.     Konstanten (Constants) .................................   302
  99.     Typen (Types) ..........................................   354
  100.     Variablen (Variables) ..................................   416
  101.     Funktionen (Functions) .................................   446
  102.     Prozeduren (Procedures) ................................   510
  103.     Spezielle Befehle ......................................   555
  104. Reservierte Worte ..........................................   592
  105. Ausdrücke ..................................................   617
  106. Fliesskomma-Arithmetik .....................................   637
  107. Die Grenzen des PCQ ........................................   660
  108. Zeichenketten (Strings) ....................................   647
  109. Compiler-Direktiven ........................................   734
  110. Typen-Konvertierungen ......................................   780
  111. Externe Verweisen (Referenzen)..............................   832
  112. Die Ein-und Ausgabe ........................................   900
  113. Fehlermeldungen ............................................  1064
  114. Laufzeit-Fehler ............................................  1091
  115. Quellennachweis ............................................  1117
  116. Einige Anmerkungen für Assembler-Programmierer .............  1176
  117. Zukünftige Erweiterungen ...................................  1189
  118. Updates ....................................................  3202
  119. Weitere Anmerkungen, Copyright und Adressen ................  1294
  120.  
  121.  
  122.  
  123.  
  124.  
  125.                Arbeiten mit dem PCQ
  126.  
  127.     Auf dieser Diskette befinden sich eine ganze Menge Files, die Sie sich
  128. vor dem ersten Einsatz des PCQ erst einmal auf eine Arbeitsdiskette
  129. kopieren sollten. Eines davon ist natürlich der Compiler selbst (Pascal) -
  130. ich gebe die Dateinamen immer in Klammern an, in einem ReadMe-File sind
  131. alle File-Namen erklärt!), selbstverständlich ebenso die
  132. Laufzeit-Bibliothek (PCQ.lib). Sollten Sie den Assembler (A68k) und den
  133. Linker (Blink) noch nicht besitzen, dann kopieren Sie sich die beiden Files
  134. ebenso auf Ihre Arbeitsdisk. Diese hier aufgelisteten Files sind sogar für
  135. die einfachsten Programme unbedingt erforderlich.
  136.  
  137.  
  138.     Alle Files mit dem Suffix ".p" sind Pascal-Beispielprogramme, die Sie
  139. sich ebenfalls auf Ihre Arbeitsdisk kopieren können. Ich arbeitete
  140. natürlich wesentlich mehr am Compiler selbst, als an diesen Beispielen,
  141. einige von diesen sind jedoch vor allem für diejenigen von Ihnen
  142. interessant, die noch nie mit Pascal gearbeitet haben. Diese Programme
  143. demonstrieren alle Möglichkeiten des Compilers, die mir bis dato
  144. eingefallen sind, deswegen sollten sie sich diese Ansehen, bevor Sie sie
  145. löschen. Der Source-Code des Compilers besteht ebenfalls aus einer Anzahl
  146. Files mit dem Suffix ".p".
  147.  
  148.     Alle Files mit dem Suffix ".i" sind Include-Files für einige System-
  149. Bibliotheken. Diese definieren die Typen, Konstanten, Prozeduren,
  150. Funktionen, Variablen und Records, die für System-Zugriffe erforderlich
  151. sind. Diese sollten Sie nach Möglichkeit mit auf Ihre Arbeitsdisk in ein
  152. Unterverzeichnis mit dem Namen "Include" kopieren. Auch einige
  153. Include-Files für Routinen in der "PCQ.lib" gehören dazu. Schaün Sie sich
  154. diese genaür an, da hier öfters etwas geändert wird. Der Code für diese
  155. Routinen ist in der "PCQ.lib".
  156.  
  157. Um nun ein Programm zu compilieren, müssen Sie erst eines mit einem
  158. Texteditor (ich empfehle DME, Anm. d. Übersetzers) schreiben, oder eines
  159. der Beispielprogramme nehmen. Dann geben Sie ein:
  160.  
  161.           1> Pascal prog.p prog.asm {-q}
  162.  
  163. wobei "Pascal" natürlich der Compiler selbst ist (den Namen können Sie
  164. nach belieben ändern). "prog.p" ist der Name der Quell-Datei des
  165. Pascalprogrammes, der natürlich auch beliebig sein kann. Der zweite
  166. Paramter ist dann der Name des zu erzeugenden Assembler-Files. Die "-q"-
  167. Direktive bewirkt, das der Compiler nur noch Fehlermeldungen ausgibt, und
  168. diese in komprimierter Form.
  169.  
  170. Beim Compilieren der Beispielprogramme kann es Probleme mit der Struktur
  171. der Unterverzeichnisse geben. Die Beispiele verlangen alle die
  172. Include-Files in einem Verzeichnis ":Include/BlaBla.i". Falls das Probleme
  173. mit der Ihrer Konfiguratiön aufwirft, müßen Sie die Include-Befehle am
  174. Anfang der Programme ändern.
  175.  
  176. Hat der Compiler keine Fehlermeldung ausgegeben, geben Sie ein:
  177.  
  178.         1> A68k prog.asm prog.o
  179.  
  180. Der Assembler erzeugt dann den Object-Code. Sollte sich auf dieser Diskette
  181. der A68k-Assembler befinden, dann sollten Sie darauf auch die entsprechende
  182. englischsprachige Anleitung zu diesem Assembler finden ("A68k.doc"). Falls
  183. nicht, benutzen Sie die Version V2.6 des A68k-Assemblers von Charlie Gibbs.
  184. Dieser Assembler führt viele kleinere Optimierungen durch, auf die sich
  185. der PCQ mehr oder weniger verlässt. Deshalb kann ich nicht behaupten, daß
  186. der PCQ-Compiler auch mit anderen Assemblern zusammenarbeitet. Am Ende
  187. müssen Sie nun das Programm "Linken", also geben Sie nun ein:
  188.  
  189.     1> Blink prog.o small.lib to prog library PCQ.lib
  190.  
  191. Hier wird nun also endlich die eigentliche ausführbare Datei mit dem Namen
  192. 'prog' erzeugt. Sämtliche Pascal-Laufzeit-Routinen, die Amiga-
  193. System-Routinen und meine eigene, kleine String-Bibliothek sind in der
  194. PCQ.lib enthalten. Sollten manche Namen von Routinen mit denjenigen, mit
  195. denen Sie selbst arbeiten, kollidieren, dann stellen Sie einfach Ihre
  196. eigenen Bibilothek-oder Object-Files in der Blink-Kommandozeile VOR die
  197. PCQ.lib. Sollten Sie noch Fragen zum Linken haben, dann sehen Sie bitte in
  198. der entsprechenden Dokumentation zu Blink mit dem Namen 'Blink.doc' nach,
  199. die sich ebenfalls auf dieser Diskette befindet.
  200.  
  201. Ich selbst verwende die Version 6.7 von "Blink"  und zweifle auch hier, ob
  202. der PCQ auch mit anderen Versionen oder sogar anderen Linkern
  203. zusammenarbeitet. "Small.lib" ist eine kleine Offsetbibliothek, die von
  204. Matt Dillon geschrieben wurde. Da in "Blink" ein kleiner Fehler existiert,
  205. muß diese Datei als Object-File statt als Bibliothek eingebunden werden.
  206. Dies erhöht aber nicht die Code-Größe des Programms.
  207.  
  208. Statt nun aber immer diese Folge von Befehlen eingeben zu müssen, können
  209. Sie auch die "make"-Batch-Datei aufrufen, die sich ebenfalls auf der
  210. Original-Pascal Diskette befinden müsste und Ihnen die eklige Tipparbeit
  211. abnimmt. Sie sollten sich dieses File jedoch vorher einmal ansehen, denn es
  212. könnte sein, dass Sie den ein oder anderen Pfad an die Verzeichnis-Strukutr
  213. Ihrer Arbeitsdiskette anpassen müssen. Es ist jedoch wichtig, die
  214. geänderte Version der "make"-Datei unbedingt wieder als Script-File
  215. kennzeichen ("protect make +s"), da diese sonst vom AmigaDOS 1.3 oder ARP
  216. nicht als Batch-Datei anerkannt wird. Aufgerufen wird diese dann wie folgt:
  217.  
  218.           1> make prog
  219.  
  220. Dabei wird dann die Datei 'prog.p' automatisch compiliert, assembliert und
  221. anschliessend zur ausführbaren Datei 'prog' gelinkt, ohne dass Sie mehr
  222. eingeben müssen. Sollten Sie in Ihr Programm natürlich andere, gesondert
  223. compilierte Units eingebunden haben, dann müssen Sie diese Batch-Datei
  224. natürlich ändern oder eine neü schreiben. Ich schlage Ihnen vor, daß Sie
  225. sich für jedes Programm, das Sie mehr als einmal compilieren wollen oder
  226. müssen (vor allem in der Entwicklungsphase) eigene Batch-Dateien schreiben,
  227. die natürlich dann andere Namen haben. Sollten Sie damit Schwierigkeiten
  228. haben, dann wenden Sie sich bitte an mich. Ich kann Ihnen dann hoffentlich
  229. eine ausführlichere Antwort auf Ihre Fragen geben.
  230.  
  231.  
  232.  
  233.  
  234.  
  235.            Fehler und Kinderkrankheiten des PCQ
  236.  
  237.  
  238. Diesen Punkt könnte ich eigentich getrost überspringen, aber trotzdem...
  239.  
  240. Wie schon erwähnt, arbeiten Sets und der "with"-Befehl überhaupt nicht.
  241. Eine Syntax, die ebenfalls nicht akzeptiert wird ist die folgende:
  242.  
  243.     type
  244.     WindowPtr = ^Window;
  245.     Window = record
  246.        NextWindow : WindowPtr;
  247.         ...
  248.  
  249. Dies bricht in der ersten Zeile mit einem "Unknown ID"-Fehler ab. Benutzen
  250. Sie stattdessen folgendes:
  251.  
  252.    type
  253.        Window = record
  254.        NextWindow : ^Window;
  255.        ....
  256.        end;
  257.        WindowPtr = ^Window;
  258.  
  259. Dies sollte in einer der nächsten Versionen beseitigt werden, aber da es
  260. nicht SOOO nötig ist...
  261.  
  262. Auch variante Records sind immer noch verboten. Dies wird demnächst
  263. beseitigt. Der bekannte Syntax, um ein einzelnes Anführungszeichen zu
  264. erzeugen (''''), wird ebenfalls nicht akzeptiert. PCQ benutzt die
  265. C-Escape-Funktion: ('\''). Näheres darüber in dem Abschnitt "Strings".
  266.  
  267.  
  268.         Vordefinierte Elemente
  269.  
  270.  
  271. Ich habe nachfolgend eine Anordnung der Elemente gewählt, wie sie in Pascal
  272. üblich ist. Nur können Sie im PCQ diese Blocks in jeder beliebigen
  273. Reihenfolge schreiben, und vor allem mehr als einmal jeden Block
  274. definieren. Mit anderen Worten: Ihre Programme können z.B so aussehen:
  275.  
  276.    Program name;
  277.    var
  278.        variable declarations
  279.    type
  280.        types
  281.    var
  282.        more variables
  283.    procedure
  284.        a procedure
  285.    var
  286.        still more variables....
  287.  
  288. Und so weiter...Natürlich muß ein Element nach wie vor erst
  289. einmal deklariert werden, bevor es gebraucht wird. Ich habe dies
  290. zugelassen, da es wirklich übel ist, einen Rattenschwanz von Include-Files
  291. zu ordnen (jedes einzelne Include-File hätte sonst in vier Abschnitte
  292. zerlegt werden müssen: In die Konstanten, die Typen, die Variablen und die
  293. Prozeduren und Funktionen).
  294.  
  295.  
  296.  
  297.  
  298.  
  299. CONST
  300.  
  301.  
  302. Die Werte für Trü und False werden als -1 und 0 definiert. Nil (Null)
  303. wird definiert als Zeiger mit dem konstanten Wert 0, ist jedoch kein
  304. reserviertes Wort wie im Standard-Pascal.
  305.  
  306. Meist, wenn der Compiler eine Konstante verlangt, nimmt er dafür einen
  307. konstanten Ausdruck (der schon während der Compilierung ausgewertet wird).
  308. Beispielsweise funktioniert Folgendes:
  309.  
  310.    const
  311.        first = 234;
  312.        second = first * 2;
  313.  
  314.    type
  315.        thetype = array [first .. first + 7] of char;
  316.  
  317.  
  318.  
  319.  
  320. Leider können Sie noch keine Standardfunktionen, Typenkonvertierungen,
  321. Realzahlen oder andere ähliche Dinge benutzen, die sonst auf Ausdrücke im
  322. Hauptprogramm anwendbar sind. Bis jetzt stehen nur die fünf mathematischen
  323. Grundfunktionen (+, -, *, div und mod) zur Verfügung. Beachten Sie auch,
  324. daß "first + 7" oben während der Compilierung ausgewertet wird, wohingegen
  325. die Berechnung des gleichen Texts im Hauptprogramm erst während der
  326. Laufzeit erfolgt. Anders gesagt: Bis jetzt besteht noch keine
  327. Konstanten-Optimierung.
  328.  
  329. Sollten Sie Integer-Konstanten verwenden, können Sie die Ziffern durch
  330. einen Unterstrich ähnlich wie bei ADA trennen:
  331.  
  332.       const
  333.       thousand = 1_000;
  334.       tenthousand = 1_0_0_0_0;
  335.  
  336. MaxInt ist als $7FFFFFFF definiert, was einen Wert über zwei Milliarden
  337. ergibt. Versuchen Sie nicht, dies zu schreiben. MaxShort ist 32767, oder
  338. $7FFF in hex.
  339.  
  340. Eine andere Form von Konstanten sind "Typen-Konstanten". Dies sieht
  341. folgendermassen aus:
  342.  
  343.     CONST
  344.         Identifier : Type Description = Constant Expression;
  345.  
  346. Typenkonstanten werden zu Beginn des Programms mit der "Constant
  347. Expression" initialisiert und können dann genauso wie Variablen benutzt
  348. werden. Dies wird im Abschnitt "Typenkonstanten" genaür beschrieben.
  349.  
  350.  
  351. TYPE
  352.  
  353. Es gibt verschiedene vordefinierte Typen.
  354.  
  355. Integer       4 Bytes, von +/- MaxInt
  356.  
  357. Short          2 Bytes. Zahlen innerhalb des Programmtexts
  358.           werden als Short-Werte angesehen, sofern sie nicht
  359.           grösser als 32767 oder kleiner als - 32767 sind.
  360.  
  361. Byte          1 Byte. Bei diesen drei Typen handelt es sich
  362.           ausnahmslos um numerische Typen, sodaß Sie sie in normalen
  363.           Ausdrücken verwenden können, ohne sich um
  364.           Typenkonvertierungen Gedanken machen zu müssen. Der Compiler
  365.           wandelt die kleinen Werte automatisch auf die verlangte
  366.           Grösse um. Denken Sie aber daran, dass momentan noch kein
  367.           Überlaufgeprüft wird. Ab Version 1.1 haben Byte-Werte den
  368.           Bereich 0..255 statt -128..127.
  369.  
  370. Real          4 Bytes (FFP-Format).
  371.  
  372. Char          1 Byte.
  373.  
  374. Boolean       1 Byte. False ist 0, Trü ist -1.
  375.  
  376. String          4 Bytes. Als "^char" definiert. Wird im
  377.           Abschnitt "Strings" noch näher erläutert.
  378.  
  379. Address       4 Bytes. Dies ist ein Zeiger auf keinen besonderen
  380.           Typ und ist zu jedem anderen Zeiger typenkompatibel
  381.           Tatsächlich ist die Konstante Nil vom Typ Address.
  382.  
  383. Text          32 Bytes. Dies ist nicht das gleiche wie ein "file
  384.           of char". Die normale Eingabe und Ausgabe bezieht
  385.           sich auf Textfiles. In Textfiles können Sie Integer-Zahlen,
  386.           Zeichen, Datenfelder (Arrays) und Strings schreiben bzw.
  387.           lesen. Auch Boolean-Werte können geschrieben werden.
  388.  
  389. Enumerated    1 oder 2 Bytes, je nach Anzahl der Aufzählungen.
  390.  
  391. Wie bereits oben erwähnt, können Sie Arrays, Zeiger, Records und Dateien,
  392. basierend auf den obengenannten Typen verwenden. Auch Synonymtypen sind
  393. einsetzbar (wie "type int = integer;").
  394.  
  395. Beachten Sie ausserdem: Überall, wo Sie einen Typen benötigen, können Sie
  396. eine vollständige Typenbeschreibung verwenden. Einige Compiler haben
  397. hierbei Probleme, und ich bin mir auch nicht sicher, was das Standard-
  398. Pascal in diesem Zusammenhang sagt, aber das ist mir eigentlich auch
  399. ziemlich egal.
  400.  
  401. In Version 1.0 mußten Mehrdimensionale Arrays ausgeschrieben werden. Es war
  402. also nicht möglich, folgendes zu schreiben:
  403.  
  404.     Array [0..5, 0..11] of Integer;
  405.  
  406.    Stattdessen mußte folgende Konstruktion benutzt werden:
  407.  
  408.     Array [0..5] of Array [0..11] of Integer;
  409.  
  410.    für die Definition, und "ArrayName[x][y]" im Programm. Da die meisten
  411.    Pascal-Compiler die Abkürzung mit Komma erlauben, ist dies nun auch in
  412.    PCQ möglich.
  413.  
  414.  
  415. VAR
  416.  
  417. Ab V1.1 hat PCQ diverse neü Variablen.
  418.  
  419.  
  420.       CommandLine   : String;
  421.  
  422. In V1.0 war dies ein Array of Char und eine Kopie der Originalzeile. Ab
  423. sofort handelt es sich dabei nur noch um einen Zeiger auf den Speicher der
  424. originalen Kommandozeile. Mit Routinen wie "GetParam" kann diese
  425. ausgewertet werden.
  426.  
  427.  
  428.       ExitProc        : String;
  429.  
  430. Diese Variable zeigt auf eine Kette von Prozeduren, die am Programmende
  431. aufgerufen werden.
  432.  
  433.       ExitCode        : Integer;
  434.  
  435. Falls das Programm normal beendet wurde, ist dies 0. Falls Exit()
  436. aufgerufen wurde, ist es das Argument des Aufrufs, ansonsten die Nummer
  437. eines Run-Time-Fehlers.
  438.  
  439.       ExitAddr        : Address;
  440.  
  441. Falls das Programm aufgrund eines Run-Time-Fehlers abgebrochen wurde,
  442. enthält diese Variable die Adresse des Befehls nach dem Fehler.
  443.  
  444.  
  445. FUNCTION
  446.  
  447.  
  448. Alle Standartfunktionen, die keine transzedentalen Funktionen benutzen,
  449. sind eingebaut.
  450.  
  451.       function ord(x : jeder Ordinaltyp): integer;
  452.      Übergibt die ordinale Position des Arguments.
  453.  
  454.       function chr(x : numerischer Typ) : char;
  455.      Übergibt das angegebene Zeichen.
  456.  
  457.       function abs(x : numerischer Typ) : der gleiche Typ;
  458.      Übergibt den absoluten Wert.
  459.  
  460.       function succ(x : ordinaler Typ) : der gleiche Typ;
  461.      Übergibt x + 1 des gleichen Typs.
  462.  
  463.       function pred(x : ordinaler Typ) : der gleiche Typ;
  464.      Übergibt x - 1 in jenem Typ.
  465.  
  466.       function trunc(x : real) : integer;
  467.      übergibt Ganzzahlanzeil
  468.  
  469.       function float(x : integer, short oder byte) : real;
  470.      verandelt x in FFP-Format.
  471.  
  472.       function floor(x : real): real;
  473.      übergibt die größte Ganzzahl kleiner als x
  474.  
  475.       function ceil(x : real): real;
  476.      übergibt die kleinste Ganzzahl größer als x
  477.  
  478.       function odd(x : numerischer Typ) : boolean;
  479.      Übergibt trü, falls Ziffer ungerade.
  480.  
  481.       function eof(x : jedes File) : boolean;
  482.      Übergibt trü, falls Sie sich am Ende einer Input-Datei
  483.      befinden.
  484.  
  485.       function adr(var x : jede Variable): Address;
  486.      übergibt die Adresse von x
  487.  
  488.       function SizeOf(t : name eines Types) : Integer;
  489.      übergibt die Größe des spezifierten Types
  490.  
  491.       function Bit(t : Integer) : Integer;
  492.      übergibt die Zahl, die der Bit-Position entspricht.
  493.  
  494.       function IOResult : Integer;
  495.      übergibt den Code des letzten IO-Befehls. Falls ungleich 0,
  496.      handelt es sich um einen AmigaDOS-Fehlercode. Der Aufruf löscht
  497.      IOResult. Falls IO-Überprüfung ausgeschaltet ist und es tritt ein
  498.      Fehler auf, wird IOResult ungleich 0 und nachfolgende IO-Befehle
  499.      werden ignoriert.
  500.  
  501. Abgesehen von den FFP-Routinen werden alle Routinen im Code eingebaut. Die
  502. anderen beiden Standardfunktionen dienen zum Öffnen von Dateien. Sie werden
  503. näher erklärt, sobald ich auf die Eingabe/Ausgabe zu sprechen komme. Von
  504. der Sprache wird auch eine Syntax wie "typename(ausdruck)" unterstÜtzt, die
  505. wie eine Funktion aussieht. Auch dies wird in einem späteren Abschnitt, der
  506. Typenkonvertierung, genaür erläutert.
  507.  
  508.  
  509. PROCEDURE
  510.  
  511.  
  512. Die Standard-Prozeduren lauten Write, Writeln, Read, Readln, Get, Put, New,
  513. Dispose, Exit und Trap. Die ersten fünf werden im Abschnitt IO behandelt.
  514. Die anderen vier sind:
  515.  
  516.       procedure New(var x : Zeigervariable);
  517.  
  518. Diese allokiert Speicher für den Platz des Variablentypes und speichert die
  519. Adresse in x. Die Speicherverwaltung beim PCQ geht mit Hilfe der
  520. AllocRemember()-Routine von Intuition vor sich, sodaß am Ende der
  521. Ausführung der ganze durch new() zugeordnete Speicher wieder an das System
  522. zurückgegeben wird. Das bedeutet, dass Sie für jedes new() nicht immer
  523. dispose() aufrufen brauchen, obwohl Sie es eigentlich sollten. Nebenbei
  524. bemerkt: Funktioniert die Zuordnung nicht, bricht das Programm ab.
  525.  
  526.       procedure Dispose(var x : Zeigervariable);
  527.  
  528. Dies gibt den zugeordneten Speicher zurück ans System. Sollte etwas
  529. durcheinander gekommen sein und Sie versuchen, Speicher zu benützen, den
  530. Sie nie zugeordnet haben, passiert nichts. Leider bedeutet das, dass Sie
  531. nie eine Fehlerdiagnose über ein Problem in Ihrem Programm erstellen
  532. können; zumindest wird aber nicht daürnd der Guru gerufen.
  533.  
  534.       procedure Exit(error : Integer);
  535.  
  536. Exit() unterbricht ein Programm vorzeitig und ist damit die einzig
  537. akzeptable Methode, ein Programm zu verlassen. Dabei wird der gleiche
  538. Vorgang wie beim normalen Abbruch eines Programms vollzogen und dann die
  539. Fehlernummer, die Sie übergeben, ans AmigaDOS übergeben. Diese Routine
  540. gibt den gesamten Speicher frei und schliesst die geöffneten Dateien. Die
  541. Fehlernummer sollte Null sein, wenn das Programm korrekt abgeschlossen
  542. wurde, 5 bei einer Warnung, 10 bei einem Fehler, und 20 bei einem
  543. katastrophalen Fehler.
  544.  
  545.       procedure Trap(num : Integer);
  546.  
  547. Das Argument für diese Prozedur muss ein konstanter Ausdruck sein, dessen
  548. Typ jedoch keine Rolle spielt. Hierbei wird einzig und allein eine
  549. 68000-Trap-Anweisung in den Code eines Befehls eingefügt. Dies ist zwar
  550. sehr praktisch bei dem Debugger, den ich verwende, ansonsten aber ziemlich
  551. nutzlos. Effektiv fügt es einen Break-Point ins Programm ein.
  552.  
  553.  
  554.                 Spezielle Befehle
  555.  
  556. Zunächst unterstützt der PCQ If-, While-, Repeat-, For-,  Case-,
  557. Goto- und With- Befehle.
  558.  
  559. Die If-, While- und Repeat-Befehle arbeiten ziemlich so, wie sie
  560. sollten. Der Case-Befehl entspricht jetzt mehr dem Standard-Pascal als in
  561. V1.0. Hier einige Beispielausdrücke:
  562.  
  563.     case Letter of             case Number * 5 of
  564.     'a'      : statement1;          -MaxInt..0 : statement1;
  565.     'b'..'g' : statement2;          1..MaxInt  : statement2;
  566.     'j',                         end;
  567.     'm'..'o',
  568.     'h'      : statement3;
  569.     else
  570.     statement4;
  571.     end;
  572.  
  573. Der For-Befehl unterstÜtzt "downto", was das Inkrement von 1 auf -1 ändert.
  574. Er unterstÜtzt auch "by" und erlaubt Ihnen damit, die Schrittweite
  575. festzulegen. Das Argument des "by"-Teils kann jeder reguläre Ausdruck sein,
  576. fÜr negative Schrittweitn mÜssen Sie aber "downto" statt "to" benÜtzen,
  577. oder die Schleife wird nur einmal ausgefÜhrt. Nebenbei bemerkt laufen
  578. For-Schleifen immer mindestens einmal ab. In jedem Fall sieht die Syntax
  579. ungefähr folgendermassen aus:
  580.  
  581.       for <Variable> := <Ausdruck> to|downto <Ausdruck>
  582.              [by <Ausdruck>]  do <Befehl>;
  583.  
  584. Der letzte Befehl ist "return", der einfach eine PROCEDURE frühzeitig
  585. abbricht. Eine FUNCTION können Sie vorzeitig abbrechen, indem Sie den
  586. Funktionsnamen einem Wert zuordnen; "return" funktioniert also nur bei
  587. Prozeduren.
  588.  
  589.  
  590.  
  591.             Reservierte Worte
  592.  
  593.  
  594. Folgende Worte sind beim PCQ reserviert:
  595.  
  596.         and     for        procedure
  597.         array    forward     program
  598.         begin    function    record
  599.         by        goto        repeat
  600.         case    if        return
  601.         const    in        set
  602.         div     label        then
  603.         do        mod        to
  604.         downto    not        type
  605.         else    of        until
  606.         end     or        var
  607.         external    packed        while
  608.         file    private     with
  609.  
  610.  
  611.  
  612.     Auch nichtimplementierte Wörter sind reserviert!
  613.  
  614.  
  615.  
  616.               Ausdrücke
  617.  
  618. Der Compiler akzeptiert den normalen Ausdrucks-Syntax, wie die meisten
  619. anderen Programmiersprachen. Auch verschiedene neue Operatioren aus Turbo
  620. Pascal und C werden unterstützt, wie:
  621.  
  622.     Xor     Ergibt die Exklusiv-Oder-Verknüpfung der zwei Operanden. Wie
  623.         Turbo-Pascal "XOR" oder "^" in C. Priorität entspricht "+" und
  624.         "-".
  625.  
  626.     Shl     Schiebt das linke Argument um n Bitpositionen nach links (1 shl
  627.         5 = 32). Priorität wie "*", "/" usw.
  628.  
  629.     Shr     Schiebt nach rechts. Es wird logisch, nicht aritmethisch
  630.         verschoeben, so ergeben negative Werte positve Resultate-
  631.  
  632. Integer-Zahlen können überall in Hexadizimaler Schreibweise angegeben
  633. werden.
  634.  
  635.  
  636.             Fliesskomma-Arithmetik
  637.  
  638. Ab V1.0c werden Real-Zahlen voll unterstützt. Real-Zahlen im Programmtext
  639. müßen in normaler Schreibweise (1234.5678 o.ä.) angegeben werden, Formate
  640. wie "1.08E-4" usw. werden NICHT unterstützt.
  641.  
  642. An mathematischen Operationen stehen nur "+", "-", "/" und "*" zur
  643. Verfügung. Der gesammte Rest der "MatfFFP.library" ist ebenfalls
  644. ansprechbar, ebenso die Funktionen Abs(), floor(), ceil(), trunc() und
  645. float().
  646.  
  647. Die Funktionen wie sin(), cos() und sqrt() sind nicht in der mathffp.lib zu
  648. finden. Diese befinden sich in der mathtrans.lib im "LIBS"-Verzeichnis fast
  649. jeder normalen Diskette. Sollten Sie jemals ein Programm schreiben, welches
  650. diese Funktionen benötigt, muß dafür die System-Diskette eingelegt sein,
  651. auf welcher diese im oben schon erwähnten "LIBS"-Verzeichnis zu finden sein
  652. müsste. Lesen Sie bitte die Informationen in MathTrans.i, falls
  653. erforderlich. übrigens habe ich nicht vor, mir eine eigene "mathtrans.lib"
  654. zu schreiben, so werden Sie die Bibliothek in Zukunft immer benötigen, wenn
  655. Sie trigonometrische oder Exponential-Funktionen einsetzen wollen.
  656.  
  657.  
  658.  
  659.           Die Grenzen des PCQ
  660.  
  661.  
  662. Der Compiler akzeptiert jede beliebige Zeilenlänge, obwohl er nur die
  663. letzten 128 eingelesenen Zeichen anzeigt, falls er einmal durch einen
  664. Fehler aussteigen sollte. Was die Länge von Files angeht, so können diese,
  665. mit wenigen Einschränkungen, so lang sein, wie Sie wollen (Denn der einzige
  666. Teil Ihres Programmes, der sich währen der Compilierung im Speicher
  667. befindet, ist das gerade eingelesene Zeichen).
  668.  
  669. Da der Compiler sehr langen Assembler-Code generiert, muss natürlich auch
  670. entsprechend Platz auf der Diskette sein. Der Assembler-Code ist immerhin
  671. ungefähr fünf Mal länger als der entsprechende Pascal-Source-Code.
  672.  
  673.  
  674.            Zeichenkettenvariablen (Strings)
  675.  
  676.  
  677. Wie vorhin schon mal erwähnt wurde, sollten Strings als '^char'- Typen
  678. angesehen werden. Das stimmt aber nur zum Teil, denn Sie haben mit Strings
  679. noch zusätzliche, spezielle Möglichkeiten. Sie können nämlich dynamisch
  680. angelegt, dimensioniert und wieder gelöscht werden. Jedem String ist ein
  681. Null-Byte nachgestellt. Beachten Sie dies also, wenn Sie einen String
  682. weiterverarbeiten wollen, sonst bringen Sie alle übrigen String-Routinen
  683. durcheinander. Im Programmtext wird jeder String mit doppelten
  684. Anführungszeichen eingegrenzt, anstelle der einfachen, wie sie in
  685. "char"-Datenfeldern zu finden sind. Also:
  686.  
  687.     "Ein String"   ist wirklich ein String, während
  688.     'Kein String'  ein array [1..11] of char ist
  689.  
  690. Eine weitere interessante Tatsache bei der Stringbehandlung ist die
  691. Möglichkeit, C-ähnliche ESCAPE-Sequenzen einzubaün. Sobald Sie einen
  692. Backslash (\) schreiben, wird das unmittelbar folgende Zeichen besonders
  693. bearbeitet. Die Sprache C besitzt davon eine Unmenge von Möglichkeiten. Bis
  694. jetzt habe ich aber nur diejenigen eingebunden, die ich selbst am meisten
  695. benötige:
  696.  
  697.     \n   wird als LineFeed -chr(10)- interpretiert
  698.     \t   wird als Tab -chr(9)- interpretiert
  699.  
  700. Alles andere läuft ohne Umänderung durch den Compiler, sodass Sie hiermit
  701. die Möglichkeit haben, sogar doppelte Anführungszeichen in Ihre Stings mit
  702. einzubauenn. Ein String wie
  703.  
  704.       "A\tboy\nand\\his \"dog.\""
  705.  
  706. wird so ausgegeben:
  707.  
  708.       |A       boy
  709.       |and\his "dog"
  710.  
  711. Im Archiv der Original-Diskette befindet sich eine Include-Datei mit dem
  712. Namen StringLib.i, die ein paar String-Routinen behandelt, nämlich die,
  713. welche ich selbst für den Compiler benötigt habe. Lesen Sie sich die
  714. Informationen zu diesem File ruhig mal durch. Sollten Sie dadurch etwas
  715. verwirrt sein, dann denken immer daran, dass diese Strings sehr ähnlich
  716. denen in der Sprache C behandelt werden und auch in den meisten Fällen
  717. ebenso verwendet werden können. Bedenken Sie, wenn Sie einen String
  718. deklarieren, dass Sie keinen Platz für die Zeichen selbst bekommen, sondern
  719. nur Platz für die Adresse, wo die Zeichen zu finden sind. Deshalb müssen
  720. Sie AllocString() in der StringLib oder etwas ähnliches aufrufen, damit die
  721. genügend Platz bekommen. Sollten Ihre Programier-Kenntnisse auf der Sprache
  722. BASIC aufgebaut sein, dann werden Sie damit am Anfang etwas Probleme haben.
  723. Ich würde vorschlagen, sich in diesem Fall die Stringbehandlung in einer
  724. Anleitung zu C einmal durchzulesen, denn ich denke, daß ein solcher Autor
  725. die Situation besser erklären kann, als ich.
  726.  
  727. Der Ausdruck "stringvar^" ist gültig und vom Typ "char". Ebenso können
  728. Strings als "stringvar[3]" angesprochen werden: Hier gilt Typ="char" und
  729. Wert = das vierte Zeichen des Strings (Index beginnt bei 0).
  730.  
  731.  
  732.  
  733.  
  734.            Compiler-Direktiven
  735.  
  736. Eventuell gibt es einmal Milliarden von verschiedenen Compiler-Befehlen,
  737. bis jetzt jedenfalls sind es nur ein paar. Sie arbeiten dabei
  738. folgendermaßen: ist das erste Zeichen im Kommentar ein Dollar-Zeichen ($),
  739. dann wird das darauffolgende Zeichen als Kommando interpretiert. Dabei
  740. dürfen keine Leerzeichen zwischen der Klammer, dem Dollar-Zeichen und dem
  741. Kommando-Zeichen sein. Ein Komma kann zum Trennen verschiedener Direktiven
  742. benutzt werden, das sieht dann so aus:
  743.  
  744.     {$O-,R+)
  745.  
  746. Nach den "I" und "A"-Direktiven können keine anderen mehr folgen, obwohl
  747. die Direktiven selber an Anderen angehangen sein können.
  748.  
  749. {$I "fname"}  Dadurch wird das File "fname" mit eingebunden. Nach
  750.           der Einbindung wird das Kommando beendet und fortgefahren
  751.           (keine weiteren Befehle sind möglich). Ab V1.0c können
  752.           Include-Files verschachtelt werden, außerdem wird automatisch
  753.           überprüft, ob ein Include-File aus Versehen zweimal
  754.           eingebunden wird.
  755.  
  756. {§A          Dieses Kommando bindet Assembler-Instruktionen mit
  757. INSTRUKTIONEN in das assemblierte File ein. Variablen und Unterprogramme zu
  758.           ermitteln. Dieser Befehl fügt alles zwischen A und der
  759.           Klammer in den Text ein.
  760.  
  761. {$R+} oder    Die '+'-Option veranlasst den Compiler, eine
  762. {$R-}          Bereichsprüfung für Arrays durchzuführen. Ab diesem Zeitpunkt
  763.           wird jeder Array-Zugriff geprüft, ob der Index-Wert innerhalb
  764.           der Grenzen des Datenfeldes liegt, bis diese Option wieder
  765.           durch den Befehl {$R-} ausgeschaltet wird. Dies erweitert und
  766.           verlangsamt den Code natürlich beträchtlich, weshalb ich dies
  767.           nur in der Testphase eines Programmes durchführen würde.
  768.           Liegt ein Index ausserhalb der Grenzen, dann bricht das
  769.           Programm mit einer Fehlermeldung ab. Defaultmäßig ist diese
  770.           Option abgeschaltet {$R-}
  771.  
  772. {$O+} oder    Mit dieser Direktive wird die IO-Überprüfung ein bzw. aus-
  773. {$O-}          geschaltet. Ist diese Option aktiviert (Voreinstellung), wird
  774.           nach jedem IO-Zugriff auf Fehler geprüft und evt. das
  775.           Programm abgebrochen.
  776.  
  777.  
  778.  
  779.  
  780.              Typen-Konvertierungen
  781.  
  782.  
  783. Sollten Sie schon mal mit MODULA-2 gearbeitet haben, dann können Sie diesen
  784. Abschnitt überspringen. Während ich an diesem Compiler arbeitete, beschloss
  785. ich, die Syntax aus MODULA-2 zu übernehmen, um den Typ eines Ausdruckes
  786. verändern zu können. Dabei müssen Sie nur den Namen eines Typen wie eine
  787. Funktion ansehen. Das funktioniert folgendermassen:
  788.  
  789.    IntegerVariable := integer(any ordinal expression);
  790.    CharVar := char(456 - 450);
  791.    if boolean('r') then ....
  792.  
  793. Dies funktioniert nun nicht nur mit den eingebundenen Standard -Typen,
  794. sondern auch bei jedem Typ, den Sie selbst schaffen. Folgendes ist
  795. ebenfalls möglich:
  796.  
  797.       type
  798.      charptr = ^char;
  799.       var
  800.      charvar : charptr;
  801.       ....
  802.      charvar := charptr(0);
  803.      charvar := charptr(integer(charvar) + 1);
  804.  
  805. Beachten Sie jedoch, das der Typ geordnet sein muss, wenn es funktionieren
  806. soll. Etwas wie:
  807.  
  808.    variable := array [1..4] of char(expression())
  809.  
  810.  
  811. wird nicht funkionieren. Dies ist der einzige Fall, in dem ein Typ möglich
  812. ist, Sie können jedoch keine Typen-Definition verwenden. In allen anderen
  813. Fällen können Sie, vielleicht...
  814.  
  815. Beachten Sie auch, dass nicht alle Typen-Konvertierungen gültig sind. Dabei
  816. ist es natürlich schlecht, Typen unterschiedlicher Grösse zu konvertieren,
  817. also z.B. einen strukturierten Typ (Array oder Record) in einen einfachen
  818. Typ. Eigentlich sollte ich ja eine Warnung vor solchen Sachen ausgeben,
  819. aber Spaß muß sein...
  820.  
  821.  
  822.  
  823.             Externe Verweise
  824.  
  825. Ab V1.1 können Funktionen ähnlich wie in anderen Pascal-Compilern als
  826. Extern deklariert werden:
  827.  
  828.     Procedure DefinedElsewhere;
  829.         External;
  830.  
  831. ...erzeugt eine externe Referenz.
  832.  
  833. Nun zu etwas weniger koscherem. Ich benötigte auch noch die entsprechende
  834. Syntax, um externen Routinen den Zugriff auf die selben globalen Variablen
  835. zu ermöglichen, wie sie im Hauptprogramm definiert wurden. Ich beschloß,
  836. ein anderes Datei-Format zu verwenden. Ein normales Pascal-Programm sieht
  837. so aus:
  838.  
  839.       program Name;
  840.       declarations
  841.       procedures and functions
  842.       begin
  843.       main program
  844.       end.
  845.  
  846.     Das externe File sieht aber so aus:
  847.  
  848.       external;
  849.       declarations (like normal)
  850.       procedure and functions (like normal)
  851.  
  852.  
  853. Dabei gibt es drei Dinge zu beachten: Erstens gibt es KEIN Hauptprogramm,
  854. zweitens gibt es keine END-Syntax, also nur eine Anordnung von Prozeduren
  855. und Funktionen bis ans Ende des Files. Und drittens gelten alle als global
  856. definierten Variablen als externe Verweise. Für den Compiler gibt es
  857. praktisch im Source-Code nur ein File, welches die globalen
  858. Variablen-Deklarationen enthält. Dieses File wird nun in sämtliche
  859. Quellfiles mit eingebunden, aber nur das Hauptprogramm reserviert den
  860. entsprechenden Speicherplatz für diese Variablen. Die anderen verweisen nur
  861. auf dieses File.
  862.  
  863. Ich denke, nun ist es Zeit, mal ein paar Worte über die Compilierung mit
  864. Hilfe eines Assemblers zu verlieren:
  865.  
  866. Erstens werden alle Prozeduren-, Funktionen- und Variablennamen als externe
  867. Verweise des Modules bestimmt, in welchem diese definiert wurden. Sollte
  868. nun eine äussere Routine auf einen von diesen Werten zugreifen wollen,
  869. sollte diese Routine zunächst nach einem File suchen, das mit einem
  870. Unterstrich "_" beginnt und ann den selben Namen hat, wie das Wort, als es
  871. das erste Mal im Programm genannt wurde. Natürlich kann Pascal dabei keine
  872. Fallunterscheidungen machen, aber ich sehe wegen dem Assembler und Linker
  873. keine andere Möglichkeit. Bedenken Sie ausserdem, daß es keine
  874. Typenüberprüfung wie in MODULA-2 durch die einzelnen Files hindurch gibt
  875. (wenn Sie dies unbedingt benötigen, dann nehmen Sie MODULA-2 für die
  876. Programmierung). Dies bedeutet, dass einer Prozedur, die einen String
  877. erwartet, auch ein Boolean-Wert zugewiesen werden kann, was wahrscheinlich
  878. einen Guru heraufbeschwört.
  879.  
  880. Zweitens müssen Sie beachten, dass der Compiler die Argumente der
  881. Prozeduren und Funktionen von links nach recht auf den Stapel schiebt. Die
  882. meisten C-Compiler machen es gerade anders herum (einschließlich Lattice
  883. und PDC). Dies bedeutet nun nicht, dass Sie deren Code und Bibliotheken
  884. nicht benutzen können, sodern nur, dass Sie die Anordnung der Argumente
  885. tauschen müssen.
  886.  
  887. Dazu noch zwei Anmerkungen:
  888.  
  889. Erstens betrachet der Compiler die Register d0, d1, d2, a0 und a1 als sein
  890. freies Betätigungsfeld und zerstört diese nach Belieben. Beim Register d2
  891. könnte es manchmal zu Problemen kommen, aber bei den anderen nicht. Falls
  892. ja, dann schaün Sie sich einfach mal den Assembler-Code an.
  893.  
  894. Die Zweite Anmerkung betrifft nur Leute, die Pascal-Programme mit anderen
  895. Sprachen linken wollen: Bedenken Sie, was der Ausdruck 'var' bedeutet und
  896. was er bewirkt und setzen Sie Ihn richtig ein.
  897.  
  898.  
  899.  
  900.                Ein- und Ausgabe
  901.  
  902.  
  903. Es gibt einige Routinen im PCQ, die die Ein- und Ausgabe betreffen. Lassen
  904. Sie mich aber zuvor noch schnell erklären, was passiert, wenn Sie ein File
  905. öffnen. Die aktuelle File-Variable, die Sie im Programm deklarieren, also:
  906.  
  907.       var
  908.      filevar : file of integer;
  909.  
  910. ist in Wirklichkeit soetwas wie ein Record, der so aussehen würde:
  911.  
  912.    file = record
  913.     HANDLE    : A DOS file handle
  914.     NEXT    : A pointer to the next file in the system list
  915.     BUFFER    : The address of the file's buffer
  916.     CURRENT : The current position within the buffer
  917.     LAST    : The Last position of a read.
  918.     MAX    : One byte past the last byte of the buffer
  919.     RECSIZE : The size of the file elements.
  920.     INTERACTIVE : A boolean value
  921.     EOF    : Another boolean value
  922.     ACCESS    : Either ModeNewFile or ModeOldFile.
  923.    end;
  924.  
  925. Auf diese Felder können Sie nicht direkt zugreifen, trotzdem werden 32
  926. Bytes Speicherplatz reserviert. Sobald Sie ein File öffnen, werden alle
  927. Felder initialisiert und das erste Element wird in den Puffer gelesen. Auf
  928. diesen Puffer kann über die filevar^-Syntax zugegriffen werden. Beachten
  929. Sie ausserdem, dass automatisch Speicherplatz für den Puffer im Speicher
  930. belegt wird, sobald die Grösse der Elemente grösser als 4 ist oder wenn
  931. diese genau 3 ist. Sollte die Grösse genau 1, 2 oder genau 4 sein (so wie
  932. z.B. bei char, short und integers), verwendet das Programm statt dem Puffer
  933. selbst den Variablenpuffer und spart so etwas Zeit und Speicherplatz.
  934. Filevar^ jedoch greift in jedem Fall auf den Puffer zu.
  935.  
  936. Sollten am Ende einer Ausführung noch einige Dateien geöffnet sein, wird
  937. der Shut-Down Code (normale Programmbeendigung oder Exit()) diese
  938. automatisch schliessen. Dies gilt jedoch nur für Files, die von Pascal aus
  939. geöffnet wurden und den Befehl open() verwendeten. Für alles, was Sie über
  940. das Amiga-DOS-Betriebssytem öffnen, sind Sie selbst verantwortlich.
  941.  
  942. Dies sind nun die IO-Routinen:
  943.  
  944.       function open(filename : string;
  945.             filevar  : file of ..., oder Text
  946.             {; BufferSize : Integer}): Boolean;
  947.  
  948. Öffnet ein File für den Schreibzugriff. Sollte ein File gleichen Namens
  949. bereits existieren, dann wird es durch diesen Befehl automatisch gelöscht.
  950. Ist alles OK, wird True zurückgegeben, ansonsten False.
  951.  
  952.      function reopen(filename : string;
  953.              filevar  : file of ..., oder Text): boolean;
  954.  
  955. Entsprechend dem open()-Befehl, nur wird hier ein existierendes File für
  956. einen Lesezugriff geöffnet.
  957.  
  958. Die restlichen Routinen entsprechen den meisten anderen Pascal-Dialekten.
  959. Der Vollständigkeit halber sind diese nun hier aufgeführt:
  960.  
  961. write()      Schreibt alles in eine Datei oder Standard-Output
  962.  
  963. writeln()    Wie write(), nur mit anschliessendem LineFeed. Nur
  964.          sinnvoll bei Text-Files.
  965.  
  966. read()       Einlesen von einer Datei oder Standard-Input
  967.          Der Befehl read(filevar,x) bewirkt:
  968.              x:= filevar^;
  969.              get(filevar);
  970.          wie es auch in den meisten anderen Pascal-Dialekten
  971.          der Fall ist.
  972.  
  973. readln()     Liest ein, wie read(), erwartet jedoch am Ende ein
  974.          LineFeed. Ist natürlich nur bei Text-Files sinnvoll.
  975.  
  976. get()        Liest das nächste Element des Files in den Puffer
  977.  
  978. put()        Schreibt Puffer auf Disk und setzt Zeiger höher
  979.  
  980. Ist das erste Argument des Einlesens oder der Ausgabe eine Variable, wird
  981. der Input-Output auf ein File umgeleitet, und nicht an das Terminal
  982. weitergegeben. Dies entspricht dem normalen Pascal und sieht so aus:
  983.  
  984.        writeln(outfile, 'Das Resultat ist ' 56 div 4);
  985.  
  986. Feldergrössen werden zwar unterstützt, und können jeden normalen Ausdruck
  987. darstellen:
  988.  
  989.       writeln((67 * 32) + 5:10);
  990.  
  991. gibt das Ergebnis mit zehn Zeichen aus. Nicht benutzte Stellen werden links
  992. mit Space-Zeichen aufgefüllt. Sollte das Ergebnis mehr Stellen benötigen,
  993. werden nur die ersten aufgefüllt und der Rest abgeschnitten. Die Feldbreite
  994. kann dabei zwischen einer Stelle minimal und dem Wert von MaxShort maximal
  995. betragen. Die Feldbreite kann für jeden beliebigen Typ im Write-Befehl
  996. spezifizieren, obwohl Sie nur in ein Text-File schreiben können.
  997.  
  998. Ich überschreite übrigens die Einschränkungen für Text-Files
  999.  innerhalb der IO mit verschiedenen Variablen-Typen:
  1000.  
  1001.        Write char      Schreibt ein Zeichen
  1002.  
  1003.        Write boolean   Schreibt True oder False ohne Leerzeichen
  1004.  
  1005.        Write integer   Schreibt die Zahl ohne Leerzeichen, aber
  1006.                möglichem Minuszeichen
  1007.  
  1008.        Write array of char
  1009.                Schreibt angegebenes Datenfeld vom ersten
  1010.                bis einschliesslich dem letzten Zeichen
  1011.  
  1012.        Write string    Schreibt vom ersten Zeichen bis, aber nicht
  1013.                einschliesslich des Null-Bytes
  1014.  
  1015.        Read char       Liest nächstes char
  1016.  
  1017.        Read boolean    Funktioniert nicht
  1018.  
  1019.        Read integer    Verarbeitet alle Leerzeichen und Tabs bis
  1020.                ein anderes Zeichen kommt, verarbeitet dann
  1021.                Ziffern bis eine Nicht-Ziffer kommt. Dabei
  1022.                wird diese Nicht-Ziffer nicht mit
  1023.                verarbeitet. Sollte die Routine ein EOLN
  1024.                (Zeilenende) finden, bevor es die erste
  1025.                Ziffer erhält, wird eine Null
  1026.                zurückgegeben.
  1027.                Sollten Buchstaben gefunden werden, bevor
  1028.                Ziffern erkannt werden, wird ebenfalls eine
  1029.                Null zurückgegeben.
  1030.  
  1031.        Read array of char
  1032.                Liest solange Zeichen in das Datenfeld, bis
  1033.                das Datenfeld voll ist, oder ein EOLN
  1034.                gefunden wird. Sollten Sie dieses EOLN
  1035.                benötigen, dann verwenden Sie lieber den
  1036.                Befehl readln. Denn read array of char kann
  1037.                EOLN nicht verarbeiten. Sollte es nämlich
  1038.                ein EOLN finden, dann wird ab dieser Stelle
  1039.                der Rest des Datenfeldes mit Leerzeichen
  1040.                aufgefüllt.
  1041.  
  1042.        Read string     Liest Zeichen ein, bis ein EOLN gefunden
  1043.                wird. Das EOLN steht immer am linken Ende
  1044.                des Datenflusses und wird dann automatisch
  1045.                durch eine Null ersetzt. Beachten Sie, dass
  1046.                diese Routine keine Längenüberprüfung
  1047.                durchführt. Sie müssen also
  1048.                sicherstellen, dass auch alle Zeichen des
  1049.                Strings eingelesen werden können.
  1050.  
  1051.        Readln           Liest alle Zeichen bis einschliesslich dem
  1052.                abschliessenden EOLN.
  1053.  
  1054. Beachten Sie bitte auch das EOF(filevar) am Ende einer Function. Ausserdem
  1055. gibt es kein dem get-Befehl entsprechenes put-Kommando. Am besten sehen Sie
  1056. sich hierzu die entsprechenden Beispiele auf der Diskette an. Beachten Sie
  1057. unbedingt, dass es hier eine Syntax gibt, die filevar^ heisst. Nicht einmal
  1058. Turbo Pascal hat so etwas. Ich denke, dass dies eine grosse Hilfe für
  1059. Programmierer sein wird.
  1060.  
  1061.  
  1062.  
  1063.  
  1064.                Fehlermeldungen
  1065.  
  1066.  
  1067. Wie ich oben schon mal erwähnt habe, werden die meisten Fehler, die Sie
  1068. machen, den Compiler total drucheinanderbringen. Dieser wird dann wohl
  1069. Fehlermeldungen ausgeben, die überhaupt nicht existieren. Sollten Sie z.B.
  1070. irgendwo einmal einmal einen Strichpunkt am Ende der Zeile vergessen, dann
  1071. erhalten Sie eine ganze Reihe von Fehlermeldungen, obwohl der Rest des
  1072. Programmes richtig compiliert wird. Auch andere Fehlerabfänge funktionieren
  1073. auf ähnliche Weise nicht zufriedenstellend. Ich hoffe, den Compiler
  1074. demnächst etwas besser gestalten zu können, aber bis jetzt bricht er immer
  1075. nach mehr als fünf Fehlermeldungen ab. Ich sah mich gezwungen, dies
  1076. einzubauen, da der Compiler manchmal nach einer Fehlermeldung selbst Fehler
  1077. bei jedem Symbol produziert und dann sogar schon bei Symbolen sich
  1078. aufhängt. Wirklich schrecklich, dieser Umstand.
  1079.  
  1080. Meistens, wenn er einen Fehler erkennt, werden die beiden letzten Zeilen,
  1081. die den Fehler verursacht haben, ausgegeben und der Teil hervorgehoben, an
  1082. dem er zuletzt gearbeitet hat. Der Fehler trat dann häufig entweder direkt
  1083. beim hervorgehobenen Symbol oder kurz davor auf. Beachten Sie auch, dass
  1084. das hervorgehobene Zeichen auch ein Punkt sein kann, was dann nicht immer
  1085. ohne weiteres erkennbar ist. In der nächsten Zeile steht die Zeilennummer,
  1086. in welcher der Fehler aufgetreten ist. Momentan werden die Fehler noch mit
  1087. Text beschrieben, also nicht nur Fehlernummern angegeben.
  1088.  
  1089.  
  1090.  
  1091.              Laufzeitfehler
  1092.  
  1093. Einige Dinge verursachen Lauzeitfehler. Diejenigen, die schon jetzt
  1094. abgefangen werden, sind:
  1095.  
  1096.       Error   Explanation
  1097.  
  1098.     50    No memory for IO buffer
  1099.     51    Read past EOF
  1100.     52    Input file not open
  1101.     53    Could not open StdInName
  1102.     54    New() failed
  1103.     55    Integer divide by zero
  1104.     56    Output file not open
  1105.     57    Could not open StdOutName
  1106.     58    Found EOF before first digit in reading an integer
  1107.     59    No digits found in reading an integer
  1108.     60    Range error
  1109.  
  1110. Die Fehlernummer wird über die exit() Funktion ans Amiga-DOS übergeben.
  1111. Läuft das Programm innerhalb einer Batch-Datei ab, können Sie anschliessend
  1112. den Return-Code sehen. Ich hoffe auch hier bis zur nächsten Version die
  1113. Fehlerbehandlung verbessert zu haben.
  1114.  
  1115.  
  1116.  
  1117.                Quellennachweis
  1118.  
  1119.  
  1120. Wie ich vorhin schon sagte, schrieb ich diesen Compiler, um zu Lernen.
  1121. Dabei habe ich natürlich bei in paar Leuten gespickt:
  1122.  
  1123. 1.
  1124.  PDC ist ein frei verteilbarer C-Compiler von Jeff Lydiatt. Dies ist ein
  1125.  ausgezeichnetes Programm und wohl zur Zeit einer der besten "umsonst" zu
  1126.  habenden Compiler für den Amiga. (Der andere ist der Draco-Compiler von
  1127.  Chris Gray). Ich lernte Vieles von diesem Compiler und verwendete diesen
  1128.  auch häufig. Als ich mir den generierten Assembler Code dieses Compilers
  1129.  angesehen habe, wurde ich inspiriert, selbst einen Compiler zu schreiben.
  1130.  
  1131. 2.
  1132.  Pascal-S ist ein Pascal-Compiler der Elektro-Technischen- Hochschule
  1133.  Zürich. Ich bekam einige Ideen über die Struktur des Compilers, aber nicht
  1134.  allzu viele.
  1135.  
  1136. 3.
  1137.  Small-C ist ein weiterer "frei verfügbarer" C-Compiler. Diese ist zwar
  1138.  nicht annähernd so mächtig wie der PDC-Compiler, aber seine Einfachheit
  1139.  half mir einige Dinge besser zu verstehen. Dieser besitzt wohl den besten
  1140.  Compiler-Source-Code, um davon zu lernen. Diesen und den PDC verwendete
  1141.  ich zum compilieren, bevor mein Compiler sich selbst compilieren konnte.
  1142.  Dabei wurden einige Design-Gesichtspunkte des Small-C-Compilers mit in
  1143.  meinen übernommen.
  1144.  
  1145. 4.
  1146.  Ein Buch mit dem Titel "Brinch Hansen on Pascal Compilers" von Per Brinch
  1147.  Hansen. Dieses Buch half mir mehr, als alle anderen Bücher, die ich zu
  1148.  diesem Thema gelesen habe, während ich den Compiler geschrieben habe. Von
  1149.  diesem Buch bekam ich vor allem gesagt, was ich alles falsch gemacht habe.
  1150.  Echt gut!
  1151.  
  1152. 5.
  1153.  Sozobon-C. Ein Freeware-C-Compiler für den Atart ST, der auf den Amiga
  1154.  umgesetzt wurde. Daraus stammen die 32-Bit-Mathe-Routinen für PCQ, ebenso
  1155.  wie ich evt. die FFP-Routinen daraus entnehmen werde.
  1156.  
  1157. 6.
  1158.  Toy-Compiler-Series in Amiga-Transactor (Beste Amiga-Zeitschrift, Anm. d.
  1159.  Übersetzers). Chris Gray, Autor von Draco, erklärt hier das Prinzip des
  1160.  Compilerbaus.
  1161.  
  1162. Wollen auch Sie die Idee der "freien" Software unterstützen, dann sehen Sie
  1163. sich doch auch eimal den Draco-Compiler von Chris Gray auf den
  1164. Fish-Disketten Nr. 76 & Nr. 77 (Update auf Fish 201), den PDC-Compiler von
  1165. Jeff Lydiatt (eine ältere Version befindet sich auf der Fish-Disk Nr. 110)
  1166. und Sozobon-C. Beide sind weit bessere Compiler als der PCQ, vor allem,
  1167. wenn Sie sich außer mit Pascal auch noch mit anderen Sprachen befassen.
  1168. Diese Compiler sind sogar besser als manche kommerziell erhältliche
  1169. Compiler. Uebrigens ist die Syntax des Draco-Compilers der eines
  1170. Pascal-Compilers sehr ähnlich.
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.       Einige Anmerkungen für Assembler-Programmierer
  1177.  
  1178.  
  1179. Während des Ablaufs eines Programmes werden die Register d0, d1, a0 und a1
  1180. benutzt. Bei IO-Aufrufen werden außerdem die Register d2 und d3 verwendet,
  1181. d2 auch wenn große Daten-Strukturen verglichen oder auf diese zugegriffen
  1182. wird. a7 ist natürlich der Stack-Zeiger und a5 der Frame-Zeiger. In a6 wird
  1183. die Basis der Bibliothek gehalten, wenn ein Systemaufruf stattfindet, und
  1184. die Belegung von a4 will ich mir für künftige Versionen des Compilers
  1185. vorbehalten (Für den Zugriff auf die lokalen Variablen von übergeordneten
  1186. Prozeduren). Die restlichen Register stehen zu Ihrer freien Verfügung.
  1187.  
  1188.  
  1189.           Zukünftige Erweiterungen
  1190.  
  1191. V1.1 enthält alle Punkte, die ich hatte einbauen wollen. Eingebaut werden
  1192. sollen nach und nach alle Besonderheiten von Turbo und Quick-Pacal. Ab V1.2
  1193. wird die Ausdrucksverarbeitung mittels Baumspeicherung verbessert.
  1194. Ansonsten werden nur noch Fehler verbessert.
  1195.  
  1196.  
  1197. [Der folgende Part wurde nicht übersetzt, einmal aus Faulheit und zum
  1198.  zweiten, weil er ziemlich sinnlos ist]
  1199.  
  1200.               Update History
  1201.  
  1202. Version 1.1a, January 20, 1990:
  1203.  
  1204.     Fixed a bug in the WriteArb routine that manifested itself
  1205. whenever you wrote to a 'File of Something'.
  1206.     Fixed a bug left in the floating point math library.  It
  1207. seems that it had not been updated for the all the 1.1
  1208. changes, so during linking it required objects that aren't
  1209. around anymore.  Since floating point math is now handled by
  1210. the compiler, I hadn't noticed it before.
  1211.     Added the Sqr() function.  Sqr(n) is the same as n * n, but
  1212. marginally faster and smaller.    Also, the compiler used to
  1213. generate lots of errors when an include file was missing.  Now
  1214. it skips the rest of the comment, like it should.
  1215.  
  1216. Version 1.1, December 1, 1989:
  1217.  
  1218.     This version is completely re-written, and has far too many
  1219. changes to list them individually here.  The main changes are the
  1220. with statement, the new IO system, a completely redesigned symbol
  1221. table, nested procedures, and several new arithmetic operators.  In
  1222. order to help port programs from Turbo Pascal and C, I added typed
  1223. constants, the Goto statement, and the normal syntax for multi-
  1224. dimensional arrays.
  1225.  
  1226. Version 1.0c, May 21, 1989:
  1227.  
  1228.     I changed the input routines around a bit, using DOS files rather
  1229. than PCQ files.  I buffered the input, and made the structure more
  1230. flexible so I could nest includes.  Rather than make up some IfNDef
  1231. directive, I decided to keep track of the file names included and
  1232. skip the ones already done.  Buffering the input cut compile times in
  1233. half.  I would not have guessed buffering would be that significant,
  1234. and I suppose I should rethink PCQ input/output in light of this.
  1235.     I added code to check for the CTRL-C, so you can break out early
  1236. but cleanly.  The Ports.i include file had a couple of errors, which
  1237. I fixed, and I also fixed the routine that opens a console for
  1238. programs programs that need one.  It used to have problems when there
  1239. were several arguments in the first write().
  1240.     I added the SizeOf() function, floating point math, and the
  1241. standard functions related to floating point math.
  1242.     There were several minor problems in the include files which I
  1243. found when I got the 1.3 includes, the first official set I've had
  1244. since 1.0.
  1245.     I relaxed the AND, OR and NOT syntax to allow any ordinal type.
  1246. This allows you to get bitwise operations on integers and whatever.
  1247. I also added a standard function called Bit(), described above.
  1248. These are all temporary until I can get sets into the language.
  1249.     I finally added string indexing.  In doing so I found a bug in
  1250. the addressing routine selector(), so I rewrote it to be more
  1251. sensible.  I think it also produces larger code, but I'm not too
  1252. worried because I'm going to add expression trees soon anyway.
  1253.  
  1254. Version 1.0b, April 17, 1989:
  1255.  
  1256.     I fixed a bug in the way complex structures were compared.    It
  1257. seems that one too many bytes were considered, so quite often the
  1258. comparison would fail.
  1259.  
  1260. Version 1.0a, April 8, 1989:
  1261.  
  1262.     This version added 32 bit math, and fixed the case statement.
  1263. The math part was just a matter of getting the proper assembly
  1264. source, but I changed the case statement completely.  Version 1.0
  1265. of the compiler produced a table that was searched sequentially for
  1266. the appropriate value, which if found was matched up with an
  1267. address.  I thought all compilers did this, but when debugging a
  1268. Turbo Pascal program at work I found that it just did a bunch of
  1269. comparisons before each statement, as if it were doing a series of
  1270. optimized if statements.  I had thought of this and rejected it as
  1271. being too simplistic, but if it's good enough for Turbo it's good
  1272. enough for me.
  1273.     The next thing I changed in this release was the startup code.
  1274. You can now run PCQ Pascal programs from the Workbench.  This was
  1275. just a matter of taking care of the Workbench message, but I also
  1276. fooled around with standard input and output.  If you try to read
  1277. or write to standard in or out from a program launched from the
  1278. Workbench, the run time code will open a window for you.
  1279.     I also fixed one bug that I found: an array index that was not
  1280. a numeric type had its type confused.  Nevermore.
  1281.  
  1282. Version 1.0, February 1, 1989
  1283.  
  1284.     Original release.
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.        Weitere Anmerkungen, Copyright und Adressen
  1293.  
  1294. Wie bereits erwähnt, liegt das Copyright für die Anleitung (auch für die
  1295. deutsche und alle anderen Übersetzungen!!!, Anm. der Übersetzers), für den
  1296. Quellcode, den Compiler und der Run-Time-Library bei (Achtung!):
  1297.  
  1298.     Copyright © 1989 Patrick Quaid
  1299.  
  1300. Es ist erlaubt, das Paket frei zu vertreiben, solange alle Datein (mit
  1301. Ausnahme des Linkers und des Assemblers, trotzdem bitte mitkopieren, falls
  1302. möglich) unverändert beigefügt sind. Der Verkauf dieses Programmapkets ist
  1303. explizit untersagt!! Es darf nur auf Disk-Sammlungen abgegeben werden, für
  1304. die ein vernünftiger Preis genommen wird (Maximum ist DM 5,- in
  1305. Deutschland). Eine Ausnahme:
  1306.  
  1307.     Stefan Ossowski, Essen, West Germany
  1308.  
  1309. ist es untersagt, PCQ in irgendeiner Form weiterzugeben, da er V1.0 zu
  1310. einem weit überhöhten Preis verkauft hat.
  1311.  
  1312. Sie können den Compiler jederzeit für Ihre eigenen Zwecke verändern, wenn
  1313. Sie wollen. Ich wäre Ihnen jedoch dankbar, wenn Sie mir dann, falls Sie
  1314. diese Version besser finden als das Original, eine Kopie zuschicken würden,
  1315. damit ich dies dann in die nächste Version mit einbinden kann. Sollten Sie
  1316. jedoch grundlegende Dinge am Compiler verändern, die nicht mehr dem
  1317. Standard von Pascal oder der obigen Beschreibung entsprechen, dann geben
  1318. Sie eine Kopie dieses modifizierten Compilers bitte NICHT unter dem Namen
  1319. PCQ weiter, da sonst nur Mißverständnisse aufkommen.
  1320.  
  1321. Dies ist kein ShareWare-Produkt, d.h. Sie müssen kein schlechtes Gewissen
  1322. haben, falls nichts bezahlen, wenn Sie es verwenden. Wenn Sie mir wirklich
  1323. helfen wollen, dann schreiben Sie mir über Ihre Erfahrungen und vor allem
  1324. über die Fehler, die Sie entdeckt haben. Sollten Sie dennoch ein Bedürfnis
  1325. verspüren, unbedingt Geld loswerden zu wollen, dann schicken Sie es an
  1326. Charlie Gibbs, der den Assembler geschrieben hat oder an die Software
  1327. Distillery, die den Linker geschrieben haben.
  1328.  
  1329. Falls Sie die aktuelle Version von mir haben wollen, schicken Sie mir $2.25
  1330. ($.50 Umschlag, Postage $.75, Disks $1). Ab Anfang 1990 ist eine gedruckte,
  1331. Ringgebunde (englische) Anleitung für ungefähr $10 erhältlich. Diese
  1332. Anleitung ist nicht identisch mit der V1.1-Anleitung, sondern wird
  1333. vollkommen neu strukturiert und mit Beispielen versehen sein.
  1334.  
  1335. Sollten Sie irgendwelche Fragen, Kommentare oder wasauchimmer haben, dann
  1336. schreiben Sie (Bitte in Englisch) an:
  1337.  
  1338.       Pat Quaid
  1339.       8320 E.Redwing
  1340.       Scottsdale, AZ 85250
  1341.       (602) 967-3356
  1342.  
  1343. Die Adresse hat sich übrigens seit V1.0 geändert!!!!! Es ist
  1344. wahrscheinlicher, mich per Post zu erreichen, obwohl ich es nicht
  1345. übelnehme, wenn es jemand per Telefon versucht.
  1346.  
  1347. Haben Sie Spaß mit dem Compiler! Falls Sie Beschwerden haben, denken Sie an
  1348. den Preis! Falls Sie etwas bezahlt haben, wenden Sie Sich an den, der das
  1349. Geld gekriegt hat!
  1350.